import { loadEnv } from '^/index'
const useSocket = (onMessageCallback: any) => {
  const { VITE_WEBSOCKET_WSS } = loadEnv()
  // 初始化websocket
  const initSocket = (socket: any) => {
    if (!socket.value.websocket) {
      // 初始化websocket
      socket.value.websocket = new WebSocket(VITE_WEBSOCKET_WSS + socket.value.url)
      // 连接开启
      socket.value.websocket.onopen = () => {
        if (socket.value.websocket.readyState === socket.value.websocket.OPEN) {
          // socket.websocket.OPEN = 1
          // 发给后端的数据需要字符串化
          socket.value.websocket.send(JSON.stringify(socket.value.message))
          // 开启心跳检测
          heartbeatCheck(socket)
        }
        if (socket.value.websocket.readyState === socket.value.websocket.CLOSED) {
          // socket.websocket.CLOSED = 3
          // 开始进行重连
          reconnect(socket)
        }
      }
      // 监听服务器端返回的信息
      socket.value.websocket.onmessage = (e: any) => {
        onMessageCallback(JSON.parse(e.data))
        // 开启心跳检测
        heartbeatCheck(socket)
      }
      // 连接关闭
      socket.value.websocket.onclose = (e: any) => {
        if (e && e.code !== 1000) {
          // 如果不是手动关闭，这里的重连会执行；如果调用了手动关闭函数，这里重连不会执行
          reconnect(socket)
        }
      }
      // 连接发生错误
      socket.value.websocket.onerror = function (e: any) {
        console.log('error', e)
        reconnect(socket)
      }
    } else {
      socket.value.websocket.send(JSON.stringify(socket.value.message))
    }
  }

  // 发送socket消息
  const send = (socket: any) => {
    if (socket.value.websocket.readyState === socket.value.websocket.OPEN) {
      // socket.websocket.OPEN = 1
      // 发给后端的数据需要字符串化
      socket.value.websocket.send(JSON.stringify(socket.value.message))
      // 开启心跳检测
      heartbeatCheck(socket)
    }
    if (socket.value.websocket.readyState === socket.value.websocket.CLOSED) {
      // socket.websocket.CLOSED = 3
      // 开始进行重连
      reconnect(socket)
    }
  }

  // 手动关闭websocket
  const close = (socket: any) => {
    if (socket.value.websocket) {
      socket.value.websocket.close() // 关闭websocket
      // socket.websocket.onclose() // 关闭websocket(如果上面的关闭不生效就加上这一条)
      // 关闭重连
      socket.value.websocket = null
      socket.value.manual = true
      socket.value.reconnectTimer && clearTimeout(socket.value.reconnectTimer)
      // 关闭心跳检查
      socket.value.heartbeatCheck.timeoutTimer && clearTimeout(socket.value.heartbeatCheck.timeoutTimer)
      socket.value.heartbeatCheck.serverTimeoutTimer && clearTimeout(socket.value.heartbeatCheck.serverTimeoutTimer)
    }
  }

  // 心跳监测
  const heartbeatCheck = (socket: any) => {
    if (socket.value.heartbeatCheck.isInit) {
      socket.value.heartbeatCheck.isInit = false
      socket.value.heartbeatCheck.timeoutTimer && clearTimeout(socket.value.heartbeatCheck.timeoutTimer)
      socket.value.heartbeatCheck.serverTimeoutTimer && clearTimeout(socket.value.heartbeatCheck.serverTimeoutTimer)
      // 15s之内如果没有收到后台的消息，则认为是连接断开了，需要重连
      socket.value.heartbeatCheck.timeoutTimer = setTimeout(() => {
        socket.value.heartbeatCheck.isInit = true
        try {
          // 这里需要看后台程序需要的是什么类型数据字段，是否需要回传token，也需要看后台程序是否做了websocket发送ping帧的功能
          socket.value.websocket?.send(JSON.stringify({ ping: true }))
        } catch (err) {
          console.log('ping error')
        }
        // console.log('socket.heartbeatCheck.serverTimeoutTimer: ', socket.value.heartbeatCheck.serverTimeoutTimer)
        // 内嵌定时器
        socket.value.heartbeatCheck.serverTimeoutTimer = setTimeout(() => {
          // socket.options.onError && socket.options.onError(transformI18n('errors.socketFail6', true))
          reconnect(socket)
        }, socket.value.heartbeatCheck.timeout)
      }, socket.value.heartbeatCheck.timeout)
    }
  }

  // 断开自动重连
  const reconnect = (socket: any) => {
    if (socket.value.reconnectTimer) {
      clearTimeout(socket.value.reconnectTimer)
      socket.value.reconnectTimer = null
    }
    socket.value.reconnectTimer = setTimeout(() => {
      if (socket.value.websocket && socket.value.websocket.readyState === socket.value.websocket.OPEN) {
        if (socket.value.reconnectTimer) {
          clearTimeout(socket.value.reconnectTimer)
          socket.value.reconnectTimer = null
        }
        return
      }
      socket.value.reConnectNum++
      if (socket.value.reConnectNum <= socket.value.reconnectLimit) {
        console.log('第', socket.value.reConnectNum, '次连接。最大连接次数：', socket.value.reconnectLimit)
        initSocket(socket)
      }
    }, socket.value.reconnectInterval)
  }

  return {
    initSocket,
    send,
    close
  }
}
export default useSocket
